package org.example.sword2offer.primary;

import java.util.Random;

/**
 * @author: lynn
 * @Descript:  用 Rand7() 实现 Rand10() leetcode 470
 *
 * https://www.bilibili.com/video/BV1VV411b7ge?from=search&seid=7311937443103948181
 *
 * @date: 2021/6/28 2:05
 * @version: 1.0
 */
public class Q75_Randon10 {
    /**
     * 1. 丢硬币，一个硬币正反面出现的次数不一定，如何产生公平事件？
     * 硬币只有两面，抛一次不是正面就是反面，数组[a,b] while true 返回 ab或者ba的话，那我就认为是公平的
     */


    /**
     * 2. 如何用random10 实现random7 ? while true random10*（7/10）==random7
     * int num=random10
     * while (true){
     *     if(num<=7) return num;
     *     num=random10;
     * }
     *
     */

    /**
     * random7 题目中提供的可以公平拿到1-7
     *
     * (random7-1)*7+random7 可以拿到 1- 49 为啥？
     * random7-1 可以公平拿到 0-6，（0-6）*7+（1-7）
     * 做到数字最少浪费！！！
     * https://www.bilibili.com/video/BV1VV411b7ge?from=search&seid=7311937443103948181
     *
     *
     */


    public int rand10() {
        //期望值至少为  2+2*(9/49)+2*(9/49)^2+.... 是一个等比梳理，所以 期望是2.45  https://www.bilibili.com/video/BV1AD4y1m7Qb?from=search&seid=5115581368217960463
        //为什么不能直接归一化，在处理 (rand7-1)/6*9+1 少了3,6,9 最主要的原因如果是连续产生整数1-7这没问题，但是要产生区间数的
        while(true){
            int num=(rand7()-1)*7+rand7(); // 1-49
            if(num<=40) return 1+num%10; // 41-49 浪费掉了
            num=(num-40-1)*7+rand7();// 1-63
            if(num<=60) return 1+num%10; //浪费了 61,62,63
            num=(num-60-1)*7+rand7(); //1-21
            if(num<=20) return 1+num%10;  //浪费了 1
        }
    }

    public int rand7() {
        Random random=new Random(7);
        return random.nextInt(7)+1;
    }
}
